﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using InfoboxParser;
using System.IO;
using System.Text.RegularExpressions;

namespace WikiExtractor
{
    class Program
    {
        const string lit = "литературное произведение";
        const string pub = "издание";

        const string name = "название";
        const string originalName = "название-оригинал";
        const string author = "автор";

        static string[] stopNames = new string[] { 
            "под", "псевдонимом", "персонаж", "юрий", "андрей", "станислав", "сергей", 
            "дмитрий", "василий", "андреевич", "александр", "александра", "сергеевич", 
            "михаил", "николаевич", "николай", "марина", "антон", "павлович", "по", 
            "александрович", "иван", "мария", "константин", "борис", "фёдор", "федор",
            "роберт", "лев", "аркадий", "владимир", "михайлович", "виктор", "владимир",
            "ник", "леонид", "максим", "васильевич", "алексей", "вячеслав", "чарльз",
            "пол", "евгений", "стивен", "дэвид", "дэниэл", "майкл"
        };
        static Regex alphabet = new Regex("^[a-zа-яёЁA-ZА-Я]$");

        static void Main(string[] args)
        {
            var extractor = new Extractor();
            var books = new List<Book>();
            foreach (var article in extractor.ExtractArticles(Settings.Default.WikiFile))
            {
                var parser = new Parser();

                var infoboxes = from box in parser.ParseInfoboxes(article.Text.Replace("\r", ""))
                                let name = box.Name.ToLower()
                                where name == lit || name == pub
                                select box;

                foreach (var item in infoboxes)
                {
                    var box = new Infobox { Name = item.Name };
                    foreach (var key in item.Attributes.Keys) box.Attributes[key.ToLower()] = item.Attributes[key];

                    books.Add(new Book
                    {
                        ArticleName = article.Title,
                        Author = box.Attributes.ContainsKey(author) ? box.Attributes[author] : "",
                        Title = box.Attributes.ContainsKey(name) ? box.Attributes[name] : "",
                        OriginalTitle = box.Attributes.ContainsKey(originalName) ? box.Attributes[originalName] : ""
                    });
                }
            }
            using (var streamWriter = new StreamWriter(Settings.Default.ExtractedBooks))
            {
                var splitter = new Regex("[^a-zа-яёЁ0-9A-ZА-Я]+");
                foreach (var book in books)
                {
                    var filtered = splitter.Split(book.Author).Where(
                        x => !stopNames.Contains(x.ToLower()) && !alphabet.IsMatch(x)
                     ).ToArray();
                    book.Author = string.Join(" ", filtered);
                }

                var serializer = new XmlSerializer(typeof(List<Book>));
                serializer.Serialize(streamWriter, books);
            }
        }
    }
}
